<?php

namespace app\admin\controller\user;

use app\common\controller\Backend;
use think\Db;
use linghuo\v2\Linghuo;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
use PhpOffice\PhpSpreadsheet\Reader\Xls;
use PhpOffice\PhpSpreadsheet\Reader\Csv;
use think\Exception;

/**
 * 提现审核管理
 *
 * @icon fa fa-circle-o
 */
class Withdraw extends Backend
{

    /**
     * UserWithdraw模型对象
     * @var \app\admin\model\UserWithdraw
     */
    protected $model = null;
    protected $noNeedRight = ['bult_audit'];

    public function _initialize()
    {
        parent::_initialize();
        $this->model = new \app\admin\model\UserWithdraw;
        $this->view->assign("typeList", $this->model->getTypeList());
        $this->view->assign("paytypeList", $this->model->getPaytypeList());
        $this->view->assign("auditstatusList", $this->model->getAuditstatusList());
        $this->view->assign("withdrawStatusList", $this->model->getWithdrawStatusList());
        $linghuos = config('thirdpay.linghuos');

        $this->view->assign("linghuos",$linghuos);
        $first = current($linghuos);
        $this->with_type = $this->request->param('with_type',$first?$first['with_type']:'');
        $this->view->assign("with_type",$this->with_type);
    }
    // protected $cookiekey = 'UserWithdrawmenu';
    // protected $cookieprefix = 'zhongjunf';
    /**
     * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
     * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
     * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
     */
    /**
     * 查看
     *
     * @return string|Json
     * @throws \think\Exception
     * @throws DbException
     */
    public function index()
    {
        //设置过滤方法
        $this->request->filter(['strip_tags', 'trim']);
        if (false === $this->request->isAjax()) {
            // \think\Cookie::set($this->cookiekey,$this->request->param('mwith_type',''),['prefix'=>$this->cookieprefix]);
            return $this->view->fetch();
        }
        if (!$this->model) {
            $result = ['total' => 0, 'rows' =>[], 'extend' => []];
            return json($result);
        }
        //如果发送的来源是 Selectpage，则转发到 Selectpage
        if ($this->request->request('keyField')) {
            return $this->selectpage();
        }
        [$where, $sort, $order, $offset, $limit] = $this->buildparams();

        $where2['with_type'] = $this->with_type;//提现类型

        $list = $this->model
            ->where($where)
            ->where($where2)
            ->order($sort, $order)
            ->paginate($limit);
        // 申请体现金额 只要未审核的都要统计
        // 总体现金额：平台成立到现在的总提现金额
        // 已审核提现金额：审核通过并且支付成功的金额
        $field = "sum(if(auditStatus = '" . $this->model::Auditstatus_0 . "',money,0)) noauditStatus";//未审核
        $field .= ",sum(if(auditStatus = '" . $this->model::Auditstatus_0 . "' AND payType IN ( '" . $this->model::PAY_TYPE_0 . "','" . $this->model::PAY_TYPE_1 . "','" . $this->model::PAY_TYPE_2 . "'),pay_money,0)) pay";// 支付中，支付完成的
        $field .= ",sum(if(payType = '" . $this->model::PAY_TYPE_2 . "',pay_money,0)) finishpay";//支付完成的
        $extend = $this->model
            ->where($where)
           ->where($where2)
            ->where('payType', 'in', [$this->model::PAY_TYPE_0, $this->model::PAY_TYPE_1, $this->model::PAY_TYPE_2]) // 0=未支付,1=支付中,2=支付成功
            // ->where('payType','=',4) // 0=未支付,1=支付中,2=支付成功
            ->where('auditStatus', 'in', [$this->model::Auditstatus_0, $this->model::Auditstatus_1]) //0=未审核,1=审核通过
            ->field($field)
            // ->fetchSql(true)
            ->select();
        // var_dump($extend[0]->toArray());exit;
        //处理银行卡号和身份证号
        foreach ($list as $k => $value) {
            //$value->idCard = substr_replace($value->idCard, str_repeat("*", 10), 4, 10);
            //$value->cardNo = substr_replace($value->cardNo, str_repeat("*", 10), 4, 8);
            $value->idCard = "'".$value->idCard;
            $value->cardNo = "'".$value->cardNo;
        }
        $result = ['total' => $list->total(), 'rows' => $list->items(), 'extend' => $extend[0]->toArray()];
        return json($result);
    }

    /**
     * 审核
     *
     * @param $ids
     * @return string
     * @throws DbException
     * @throws \think\Exception
     */
    public function audit($ids = null)
    {
        $today = date('Ymd');
        if (time() < strtotime($today.'090000') || time() > strtotime($today.'180000')  ) {
           // $this->error(__('提现审核请于10：00~18：00操作'));
        }
        $pattern = Db::name("config")->where(['name'=>'pattern'])->value('value');
        if(isset($pattern) && $pattern == 2){
            $this->error(__('提现通道关闭，请联系技术'));
        }
        $row = $this->model->get($ids);
        if (!$row) {
            $this->error(__('No Results were found'));
        }
        $adminIds = $this->getDataLimitAdminIds();
        if (is_array($adminIds) && !in_array($row[$this->dataLimitField], $adminIds)) {
            $this->error(__('You have no permission'));
        }
        if (false === $this->request->isPost()) {
            $this->view->assign('row', $row);
            return $this->view->fetch();
        }
        $params = $this->request->post('row/a');
        if (empty($params)) {
            $this->error(__('Parameter %s can not be empty', ''));
        }
        $params = $this->preExcludeFields($params);
        $result = false;
        Db::startTrans();
        try {
            //是否采用模型验证
            if ($this->modelValidate) {
                $name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
                $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.edit' : $name) : $this->modelValidate;
                $row->validateFailException()->validate($validate);
            }
            $updateParams = [];
            if (in_array($row['auditStatus'], [$this->model::Auditstatus_1, $this->model::Auditstatus_2])) {
                Db::rollback();
                $this->error(__('Reviewed'));//通过不能再审核
            } elseif ($params['auditStatus'] == $this->model::Auditstatus_2 && empty($params['auditMsg'])) {
                Db::rollback();
                $this->error(__('Please fill in the reason for the audit failure'));
            }
            if ($params['auditStatus'] == 1) {
                $connfig = config('thirdpay.linghuos');
                $linghuo = (new Linghuo($connfig[$row['with_type']]))->info();

                // $linghuo = (new Linghuo)->info();
                if ($linghuo['code'] !== 1) {
                    Db::rollback();
                    $this->error($linghuo['msg']);
                }
                if (floatval($linghuo['data']['result']['availableFee']) < $row['money']) {
                    Db::rollback();
                    $this->error(__('Available amount is less than withdrawal amount'));
                }
            }

            if ($params['auditStatus'] == $this->model::Auditstatus_2) {
                $shareUserOne = \app\admin\model\share\ShareUser::where('user_id', '=', $row->user_id)->find();
                if (!$shareUserOne || $shareUserOne->lock_money < $row['money']) {
                    $updateParams['payMsg'] = '系统异常：锁定余额' . ($shareUserOne ?$shareUserOne->lock_money:'用户注销') . '小于提现余额' . $row['money'];
                } else {
                    $shareUserOne->unlock_money($shareUserOne, $row['money'], $shareUserOne::UNLOCK_MONEY_TRUE,0, $row['with_type']);
                }
            }

            $updateParams['auditStatus'] = $params['auditStatus'];
            $updateParams['auditMsg'] = $params['auditStatus'] != $this->model::Auditstatus_2 ? '' : $params['auditMsg'];
            $updateParams['auditUserId'] = $this->auth->id;
            $updateParams['auditUsername'] = $this->auth->username;
            $updateParams['auditTime'] = time();
            $result = $row->allowField(true)->save($updateParams);
            Db::commit();
        } catch (ValidateException|PDOException|Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }
        if (false === $result) {
            $this->error(__('No rows were updated'));
        }
        $this->success();
    }

    /**
     * 批量更新
     *
     * @param $ids
     * @return void
     */
    public function multi($ids = null)
    {
        $pattern = Db::name("config")->where(['name'=>'pattern'])->value('value');
        if(isset($pattern) && $pattern == 2){
            $this->error(__('提现通道关闭，请联系技术'));
        }
        if (false === $this->request->isPost()) {
            $this->error(__('Invalid parameters'));
        }
        $ids = $ids ?: $this->request->post('ids');
        if (empty($ids)) {
            $this->error(__('Parameter %s can not be empty', 'ids'));
        }

        if (false === $this->request->has('params')) {
            $this->error(__('No rows were updated'));
        }
        parse_str($this->request->post('params'), $values);
        $values = $this->auth->isSuperAdmin() ? $values : array_intersect_key($values, array_flip(is_array($this->multiFields) ? $this->multiFields : explode(',', $this->multiFields)));
        if (empty($values)) {
            $this->error(__('You have no permission'));
        }
        $where = [];

        // $config = config('thirdpay.linghuo');
        // $with_type = $config['with_type'];

        // $where['with_type'] = $with_type;//提现类型
        // $where['with_type'] = \think\Cookie::get($this->cookiekey,$this->cookieprefix);//提现类型

        $today = date('Ymd');
        // 审核
        if (isset($values['auditStatus']) && (time() < strtotime($today.'090000') || time() > strtotime($today.'180000'))  ) {
            $this->error(__('提现审核请于10：00~18：00操作'));
        }elseif (isset($values['auditStatus']) && $values['auditStatus'] != $this->model::Auditstatus_1) {
            $this->error(__('Batch approval can only be approved'));
        } elseif (isset($values['auditStatus'])) {
            $values['auditUserId'] = $this->auth->id;
            $values['auditUsername'] = $this->auth->username;
            $values['auditTime'] = time();
            $where['auditStatus'] = $this->model::Auditstatus_0;// 未审核的
        }
        // 重新支付
        if (isset($values['payType'])&& (time() < strtotime($today.'090000') || time() > strtotime($today.'180000')) ) {
            $this->error(__('提现审核请于10：00~18：00操作'));
        }elseif (isset($values['payType']) && $values['payType'] != $this->model::PAY_TYPE_0) {
            $this->error(__('支付状态只有修改为未支付'));
        } elseif (isset($values['payType'])) {
            $values['auditUserId'] = $this->auth->id;
            $values['auditUsername'] = $this->auth->username;
            $values['auditTime'] = time();
            $where['payType'] = $this->model::PAY_TYPE_3;//支付失败的
        }
        $adminIds = $this->getDataLimitAdminIds();
        if (is_array($adminIds)) {
            $this->model->where($this->dataLimitField, 'in', $adminIds);
        }
        $count = 0;
        Db::startTrans();
        try {

            $list = $this->model
                ->where($this->model->getPk(), 'in', $ids)
                ->where($where)
                ->lock(true)
                // ->fetchSql(true)
                ->select();
            foreach ($list as $item) {
                // var_dump($item->with_type);
                if (isset($values['payType'])) {// 修改未支付
                    $shareUserOne = \app\admin\model\share\ShareUser::where('user_id', '=', $item->user_id)->find();
                    // 用户注销
                    if (!$shareUserOne) {
                        continue;
                    }
                    // $price = 0;
                    // if($item->with_type == $item::WITH_TYPE_1){
                    //     $price = floatval($shareUserOne->old_price);
                    // }elseif ($item->with_type == $item::WITH_TYPE_2){
                    //     $price = floatval($shareUserOne->advert_price);
                    // }elseif ($item->with_type == $item::WITH_TYPE_0){
                    //     $price = floatval($shareUserOne->price);
                    // }
                    // 余额不足
                    if (floatval($shareUserOne->lock_money) < $item->money) {
                        continue;
                    }
                    // 锁定余额
                    // $shareUserOne->lock_money($shareUserOne, $item['money'], $item->with_type);
                }
                // 如果为重新支付
                $count += $item->allowField(true)->isUpdate(true)->save($values);
            }
            Db::commit();
        } catch (PDOException|Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }
        // exit();
        if ($count) {
            $this->success();
        }
        $this->error(__('No rows were updated'));
    }

    /**
     * [much 比对多余订单]
     * @return [type]     [description]
     * @since  2022-10-17
     */
    public function much()
    {
        if (false === $this->request->isAjax()) {
            return $this->view->fetch();
        }
        $list = [];
        $result = ['total' => count($list), 'rows' => $list, 'code' => 1];
        $file = $this->request->request('file');
        if (!$file) {
            $result['msg'] = __('Parameter %s can not be empty', 'file');
            return json($result);
        }
        $hooks = config('addons.hooks');
        $filePath = ROOT_PATH . DS . 'public' . DS . $file;
        if (!empty($hooks['upload_config_init'])) {
            $third = get_addon_config($hooks['upload_config_init'][0]);

            $remotefile = fopen($third['cdnurl'] . $file, 'r');
            $fh = fopen($filePath, 'w');

            while (!feof($remotefile)) {
                $output = fread($remotefile, 8192);
                fwrite($fh, $output);
            }
            fclose($remotefile);
        }

        if (!is_file($filePath)) {
            $result['msg'] = __('No results were found', 'file');
            return json($result);
            $this->error(__('No results were found'));
        }
        //实例化reader
        $ext = pathinfo($filePath, PATHINFO_EXTENSION);
        if (!in_array($ext, ['csv', 'xls', 'xlsx'])) {
            $result['msg'] = __('Unknown data format');
            return json($result);
        }
        if ($ext === 'csv') {
            $file = fopen($filePath, 'r');
            $filePath = tempnam(sys_get_temp_dir(), 'import_csv');
            $fp = fopen($filePath, 'w');
            $n = 0;
            while ($line = fgets($file)) {
                $line = rtrim($line, "\n\r\0");
                $encoding = mb_detect_encoding($line, ['utf-8', 'gbk', 'latin1', 'big5']);
                if ($encoding !== 'utf-8') {
                    $line = mb_convert_encoding($line, 'utf-8', $encoding);
                }
                if ($n == 0 || preg_match('/^".*"$/', $line)) {
                    fwrite($fp, $line . "\n");
                } else {
                    fwrite($fp, '"' . str_replace(['"', ','], ['""', '","'], $line) . "\"\n");
                }
                $n++;
            }
            fclose($file) || fclose($fp);

            $reader = new Csv();
        } elseif ($ext === 'xls') {
            $reader = new Xls();
        } else {
            $reader = new Xlsx();
        }

        //加载文件
        $insert = [];
        try {
            if (!$PHPExcel = $reader->load($filePath)) {
                $result['msg'] = __('Unknown data format');
                return json($result);

            }
            $currentSheet = $PHPExcel->getSheet(0);  //读取文件中的第一个工作表
            $allColumn = $currentSheet->getHighestDataColumn(); //取得最大的列号
            $allRow = $currentSheet->getHighestRow(); //取得一共有多少行
            $maxColumnNumber = Coordinate::columnIndexFromString($allColumn);
            // Log::info($allRow);
            $i = 0;
            for ($currentRow = 4; $currentRow <= $allRow; $currentRow++) {

                $orderNo = $currentSheet->getCellByColumnAndRow(7, $currentRow)->getValue();//交易流水号
                $pay_money = $currentSheet->getCellByColumnAndRow(8, $currentRow)->getValue();//实得金额
                $memberName = $currentSheet->getCellByColumnAndRow(9, $currentRow)->getValue();//客户名称
                $idCard = $currentSheet->getCellByColumnAndRow(10, $currentRow)->getValue();//身份证号
                $phone = $currentSheet->getCellByColumnAndRow(11, $currentRow)->getValue();//手机号
                $cardNo = $currentSheet->getCellByColumnAndRow(12, $currentRow)->getValue();//到账卡号
                $one = $this->model->where(['orderNo' => $orderNo])->find();
                $insert[] = [
                    'orderNo' => $orderNo,
                    'pay_money' => $pay_money,
                    'memberName' => $memberName,
                    'idCard' => strtoupper($idCard),
                    'phone' => $phone,
                    'cardNo' => $cardNo,
                ];

                if ($one && $one->payType == '2') {
                    continue;
                }

                $idCarddata = $this->model->where(['idCard' => $idCard])->select();

                $msg = '订单不在';
                if (!$one && $idCarddata) {
                    $orders = [];
                    foreach ($idCarddata as $value) {
                        // 姓名 金额 卡号 身份证 一样就保存单号
                        if ($value->memberName == $memberName && ($pay_money == $value->money || $pay_money == sprintf('%.2f', $value->money * 0.95)) && $value->cardNo == $cardNo) {
                            $orders[] = $value->order_sn;
                            // $value->$orderNo = $orderNo;
                            // $value->save();
                        }
                    }
                    $msg = implode(',', $orders);
                }
                $list[] = [
                    'id' => $i++,
                    'orderNo' => $orderNo,
                    'pay_money' => $pay_money,
                    'memberName' => $memberName,
                    'idCard' => strtoupper($idCard),
                    'phone' => $phone,
                    'cardNo' => $cardNo,
                    'msg' => !empty($one) ? ('订单号：' . $one->orderNo) : $msg,
                    // 'payType_text'=>$one->payType_text,
                    // 'sql'=>$this->model->where(['orderNo'=>$orderNo,'payType'=>'2'])->fetchSql(true)->find(),
                ];
            }
        } catch (Exception $exception) {
            $result['msg'] = $exception->getMessage();
            return json($result);
        }

        $result = ['total' => count($list), 'rows' => $list, 'code' => 1, 'insert' => $insert];

        return json($result);
    }

}
